package com.atguigu.java8.streamDemo;

import com.atguigu.java8.lambdaDemo.Employee;
import org.junit.Test;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Stream;

/**
 * @author Xiaohong X Gou
 * @createTime 2022-10-11 16:43
 * @description
 * 一、Stream的三个操作步骤
 *
 * 1、创建Stream
 *
 * 2、中间操作
 *
 * 3、终止操作（终端操作）
 */
public class TestStreamAPI2 {
    //中间操作
    /*
        筛选与切片
        filter-接收Lambda，从流中排除某些元素
        limit-截断流,使其元素不超过指定数量
        skip(n)-跳过元素，返回一个扔掉了前n个元素的流。若流中元素不足n个，则返回一个空流。与limit(n)互补
        distinct-筛选，通过流生成元素的hashCode()和equals()去除重复元素
    */
    List<Employee> employees = Arrays.asList(
            new Employee(1,"张三",18,9999.99),
            new Employee(2,"李四",38,5555.99),
            new Employee(3,"王五",50,6666.66),
            new Employee(4,"赵六",16,3333.33),
            new Employee(5,"田七",12,8888.88)
    );

    //内部迭代：迭代操作由Stream流完成
    @Test
    public void test1(){
        //中间操作：不会执行任何操作
        Stream<Employee> stream = employees.stream()
                .filter((e) -> {
                    System.out.println("StreamAPI的中间操作");
                    return e.getAge() > 35;
                    });

        //终止操作：一次性执行全部内容,即“惰性求值”
        stream.forEach(System.out::println);
    }

    //外部迭代
    @Test
    public void test2(){
        Iterator<Employee> iterator = employees.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

    @Test
    public void test3(){
        employees.stream()
                .filter((e)->{
                    System.out.println("短路");
                   return e.getSalary()>5000;
                })
                .limit(2)
                .forEach(System.out::println);
    }

    @Test
    public void test4(){
        employees.stream()
                .filter(e->{
                    System.out.println("短路");
                    return e.getSalary()>5000;
                })
                .skip(2)
                .distinct()
                .forEach(System.out::println);
    }
    /*
        映射
        map-接收Lambda,将元素转换成其他形式提取信息。接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素。
        flatMap-接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流
     */
    @Test
    public void test5(){
        List<String> list=Arrays.asList("aaa","bbb","ccc","ddd","eee");

        list.stream()
                .map((str)->str.toUpperCase(Locale.ROOT))
                .forEach(System.out::println);

        System.out.println("..................");

        employees.stream()
                .map(Employee::getName)
                .forEach(System.out::println);

        System.out.println("...............");

        Stream<Stream<Character>> stream = list.stream()
                .map(TestStreamAPI2::filterCharacter);

        stream.forEach((sm)->sm.forEach(System.out::println));

        Stream<Character> characterStream = list.stream()
                .flatMap(TestStreamAPI2::filterCharacter);
        characterStream.forEach(System.out::println);
    }
    public static  Stream<Character> filterCharacter(String str){
        List<Character> list=new ArrayList<>();
        for (Character ch:str.toCharArray()){
            list.add(ch);
        }
        return list.stream();
    }
    //中间操作
    /*
       排序
       sorted()-自然排序(Comparable)
       sorted(comparator com)-定制排序
     */
    @Test
    public void test7(){
        List<String> list=Arrays.asList("bbb","ccc","ddd","eee","aaa");
        list.stream()
                .sorted()
                .forEach(System.out::println);

        System.out.println("...................");

        employees.stream()
                .sorted((e1,e2)->{
                    if (e1.getAge()==e2.getAge()){
                        return e1.getName().compareTo(e2.getName());
                    }else {
                        return e1.getAge()-e2.getAge();
                    }
                })
                .forEach(System.out::println);
    }
}
